package junit.samples.money; import java.util.*; /** * A MoneyBag defers exchange rate conversions. For example adding * 12 Swiss Francs to 14 US Dollars is represented as a bag * containing the two Monies 12 CHF and 14 USD. Adding another * 10 Swiss francs gives a bag with 22 CHF and 14 USD. Due to * the deferred exchange rate conversion we can later value a * MoneyBag with different exchange rates. * * A MoneyBag is represented as a list of Monies and provides * different constructors to create a MoneyBag. */ class MoneyBag implements IMoney { private Vector fMonies= new Vector(5); private MoneyBag() { } MoneyBag(Money bag[]) { for (int i= 0; i < bag.length; i++) { if (!bag[i].isZero()) appendMoney(bag[i]); } } MoneyBag(Money m1, Money m2) { appendMoney(m1); appendMoney(m2); } MoneyBag(Money m, MoneyBag bag) { appendMoney(m); appendBag(bag); } MoneyBag(MoneyBag m1, MoneyBag m2) { appendBag(m1); appendBag(m2); } public IMoney add(IMoney m) { return m.addMoneyBag(this); } public IMoney addMoney(Money m) { return (new MoneyBag(m, this)).simplify(); } public IMoney addMoneyBag(MoneyBag s) { return (new MoneyBag(s, this)).simplify(); } private void appendBag(MoneyBag aBag) { for (Enumeration e= aBag.fMonies.elements(); e.hasMoreElements(); ) appendMoney((Money)e.nextElement()); } private void appendMoney(Money aMoney) { IMoney old= findMoney(aMoney.currency()); if (old == null) { fMonies.addElement(aMoney); return; } fMonies.removeElement(old); IMoney sum= old.add(aMoney); if (sum.isZero()) return; fMonies.addElement(sum); } private boolean contains(Money aMoney) { Money m= findMoney(aMoney.currency()); return m.amount() == aMoney.amount(); } public boolean equals(Object anObject) { if (isZero()) if (anObject instanceof IMoney) return ((IMoney)anObject).isZero(); if (anObject instanceof MoneyBag) { MoneyBag aMoneyBag= (MoneyBag)anObject; if (aMoneyBag.fMonies.size() != fMonies.size()) return false; for (Enumeration e= fMonies.elements(); e.hasMoreElements(); ) { Money m= (Money) e.nextElement(); if (!aMoneyBag.contains(m)) return false; } return true; } return false; } private Money findMoney(String currency) { for (Enumeration e= fMonies.elements(); e.hasMoreElements(); ) { Money m= (Money) e.nextElement(); if (m.currency().equals(currency)) return m; } return null; } public int hashCode() { int hash= 0; for (Enumeration e= fMonies.elements(); e.hasMoreElements(); ) { Object m= e.nextElement(); hash^= m.hashCode(); } return hash; } public boolean isZero() { return fMonies.size() == 0; } public IMoney multiply(int factor) { MoneyBag result= new MoneyBag(); if (factor != 0) { for (Enumeration e= fMonies.elements(); e.hasMoreElements(); ) { Money m= (Money) e.nextElement(); result.appendMoney((Money)m.multiply(factor)); } } return result; } public IMoney negate() { MoneyBag result= new MoneyBag(); for (Enumeration e= fMonies.elements(); e.hasMoreElements(); ) { Money m= (Money) e.nextElement(); result.appendMoney((Money)m.negate()); } return result; } private IMoney simplify() { if (fMonies.size() == 1) return (IMoney)fMonies.elements().nextElement(); return this; } public IMoney subtract(IMoney m) { return add(m.negate()); } public String toString() { StringBuffer buffer = new StringBuffer(); buffer.append("{"); for (Enumeration e= fMonies.elements(); e.hasMoreElements(); ) buffer.append((Money) e.nextElement()); buffer.append("}"); return buffer.toString(); } }